package com.zcxy.fast.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxy.fast.bean.PageQuery;
import com.zcxy.fast.bean.TreeNode;
import com.zcxy.fast.constant.CommonConstant;
import com.zcxy.fast.entity.SysMenu;
import com.zcxy.fast.mapper.SysMenuMapper;
import com.zcxy.fast.mybatisExtend.BaseServiceImpl;
import com.zcxy.fast.mybatisExtend.LambdaValiteCondition;
import com.zcxy.fast.mybatisExtend.RelationHelper;
import com.zcxy.fast.pojo.RouterMeta;
import com.zcxy.fast.pojo.VueRouter;
import com.zcxy.fast.service.ISysMenuService;
import com.zcxy.fast.utils.BeanCopyUtil;
import com.zcxy.fast.utils.JwtUtil;
import com.zcxy.fast.utils.StringUtils;
import com.zcxy.fast.utils.TreeUtil;
import com.zcxy.fast.vo.SysMenuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 平台-菜单表业务层处理
 *
 * @author zcc
 * @email 860474958@qq.com
 * @date 2021-02-02 08:48:57
 */
@Service
@Slf4j
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Override
    public IPage<SysMenuVo> queryPageList(PageQuery<SysMenu> queryVo) {
        SysMenu sysMenu = queryVo.getT() == null ? new SysMenu() : queryVo.getT();
        if (sysMenu != null && StringUtils.isEmpty(sysMenu.getParentId())) {
            sysMenu.setParentId("0");
        }
        QueryWrapper queryWrapper = new QueryWrapper(sysMenu);
        Page page = new Page(queryVo.getPageNo(), queryVo.getPageSize());
        queryWrapper.orderByDesc("create_time");


        IPage<SysMenu> iPage = baseMapper.selectPage(page, queryWrapper);
        IPage<SysMenuVo> voIPage = BeanCopyUtil.copyPage(iPage, SysMenuVo.class);
        if (CollectionUtil.isNotEmpty(voIPage.getRecords())) {
            RelationHelper.renderList(voIPage.getRecords());
        }
        return voIPage;
    }

    @Override
    public List<SysMenuVo> queryList(SysMenu sysMenu) {
        SysMenu sysMenuq = sysMenu == null ? new SysMenu() : sysMenu;
        QueryWrapper queryWrapper = new QueryWrapper(sysMenuq);
        List<SysMenuVo> SysMenuVos = BeanCopyUtil.copyListToList(baseMapper.selectList(queryWrapper), SysMenuVo.class);
        return SysMenuVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysMenu(SysMenu sysMenu) {
        if (StringUtils.isEmpty(sysMenu.getParentId())) {
            sysMenu.setParentId("0");
        }
        LambdaValiteCondition<SysMenu> valiteCondition = LambdaValiteCondition.newInstance(sysMenu);
        valiteCondition.clear();
        valiteCondition.addField(SysMenu::getMenuType, SysMenu::getName).addErrInfo("菜单类型,菜单名称 不能重复");
        validFiledExist(valiteCondition);
        baseMapper.insert(sysMenu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysMenu(SysMenu sysMenu) {
        if (StringUtils.isEmpty(sysMenu.getParentId())) {
            sysMenu.setParentId("0");
        }
        LambdaValiteCondition<SysMenu> valiteCondition = LambdaValiteCondition.newInstance(sysMenu);
        valiteCondition.clear();
        valiteCondition.addField(SysMenu::getMenuType, SysMenu::getName).addErrInfo("菜单类型,菜单名称 不能重复");
        valiteCondition.addExcludes(SysMenu::getId);
        validFiledExist(valiteCondition);


        baseMapper.updateById(sysMenu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAllSysMenu(List<String> ids) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("id", ids);
        baseMapper.delete(queryWrapper);
    }

    @Override
    public List<Map> queryTreeNodeList(String parentId) {
        List<Map> treeNodes = new ArrayList<>();
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper();
        if (StringUtils.isEmpty(parentId)) {
            queryWrapper.eq(SysMenu::getParentId, "0");
        } else {
            queryWrapper.eq(SysMenu::getParentId, parentId);
        }
        List<SysMenu> sysMenus = baseMapper.selectList(queryWrapper);
        List<SysMenuVo> sysMenuVos = BeanCopyUtil.copyListToList(sysMenus, SysMenuVo.class);
        RelationHelper.renderList(sysMenuVos);
        if (CollectionUtil.isNotEmpty(sysMenuVos)) {
            sysMenuVos.forEach(i -> {
                TreeNode treeNode = new TreeNode();
                treeNode.setKey(i.getId());
                treeNode.setLabel(i.getName());
                treeNode.setHasChildren(i.isHasChildren());
                treeNode.setParentId(i.getParentId());
                treeNodes.add(treeNode.getAttributes());
            });
        }
        return treeNodes;
    }

    @Override
    public List<TreeNode> queryTreeNodeList() {
        List<SysMenu> sysMenus = baseMapper.selectList(new QueryWrapper<>());
        List<TreeNode> treeNodes = new ArrayList<>();
        List<TreeNode> allNodes = BeanCopyUtil.copyListToList(sysMenus, TreeNode.class, (s, t) -> {
            t.setKey(s.getId());
            t.setParentId(s.getParentId());
            t.setLabel(s.getName());
        });
        if (CollectionUtil.isNotEmpty(allNodes)) {
            treeNodes = allNodes.stream().filter(i -> {
                return i.getParentId().equals("0");
            }).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(treeNodes)) {
                treeNodes.forEach(i -> {
                    TreeUtil.deepGenTree(allNodes, i);
                });
            }
        }
        return treeNodes;
    }


    /**
     * 功能描述:根据登录用户查询绑定的菜单
     *
     * @param:
     * @return:
     * @auther: zcc
     * @date: 2019/10/17 22:43
     */
    @Override
    public List<VueRouter<SysMenu>> queryUserMenu() {
        String loginName = JwtUtil.getLoginUser().getLoginName();
        // List<SysMenu> list = sysMenuMapper.findUserMenu(loginName);
        //TODO 先暂时获取启用的菜单
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper();
        //启用的且类型不是权限的
        wrapper.in(SysMenu::getMenuType, CommonConstant.MENU_TYPE_1, CommonConstant.MENU_TYPE_2);

        List<SysMenu> list = baseMapper.selectList(new QueryWrapper<>());
        List<VueRouter<SysMenu>> treeList = new ArrayList<>();
        List<VueRouter<SysMenu>> routes = new ArrayList<>();
        list.forEach(menu -> {
            if (menu.getMenuType().equals(CommonConstant.MENU_TYPE_1) || menu.getMenuType().equals(CommonConstant.MENU_TYPE_2)) {
                VueRouter<SysMenu> route = new VueRouter<>();
                route.setId(menu.getId());
                route.setParentId(menu.getParentId());
                route.setPath(menu.getUrl());
                route.setComponent(menu.getComponent());
                route.setSysType(menu.getMenuType());
                route.setName(menu.getName());
                route.setRedirect(menu.getRedirect());
                route.setMeta(new RouterMeta(menu.getName(), menu.getIcon(), true));
                routes.add(route);
            }
        });
        getMenuTreeVoList(treeList, routes);
        return treeList;
    }

    private void getMenuTreeVoList(List<VueRouter<SysMenu>> treeList, List<VueRouter<SysMenu>> menuList
    ) {
        if (CollectionUtil.isNotEmpty(menuList)) {
            //第一层数据
            List<VueRouter<SysMenu>> menuListFirst = menuList.stream().filter(i -> {
                return CommonConstant.MENU_TYPE_1.equals(i.getSysType());
            }).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(menuListFirst)) {
                menuListFirst.forEach(k -> {
                    List<VueRouter<SysMenu>> menuListSecond = menuList.stream().filter(i -> {
                        return k.getId().equals(i.getParentId()) && CommonConstant.MENU_TYPE_2.equals(i.getSysType());
                    }).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(menuListSecond)) {
                        k.setChildren(menuListSecond);
                        treeList.add(k);
                    }
                });
            }
        }

    }
}
